#pragma once

enum LogSeverity
{
  lsNone    = 0x00,
  lsError   = 0x01,
  lsWarning = 0x02,
  lsInfo    = 0x04,
  lsTimer   = 0x08,
  lsSystem  = 0x10,
  lsAll     = 0xFF,

#ifdef _DEBUG
  lsDefault = lsAll
#else
  lsDefault = lsSystem | lsError | lsWarning
#endif
};

class Logger
{
public:
  static void BeginLog(TCHAR* file, DWORD sev = lsDefault);
  static void EndLog();

  static void SetSeverity(DWORD sev);

  static void Log(LogSeverity sev, const TCHAR* d);
  static void Log(LogSeverity sev, int d);
  static void Log(LogSeverity sev, long d);

  static void LogFmt(LogSeverity sev, const TCHAR* fmt, ...);

  static void LogCePropVal(LogSeverity sev, const TCHAR* label, CEPROPVAL& prop);
  static const TCHAR* GetCePropName(CEPROPID propId);

  static void LogTimestamp(LogSeverity sev = lsInfo);
  static void LogLastError(LogSeverity sev = lsError);

private:
  static HANDLE hFile;
  static TCHAR  buf[2048];
  static DWORD  severity;
};

#ifdef LOG_ENABLED

#define BEGINLOG(x, s) Logger::BeginLog(x, s)
#define ENDLOG() Logger::EndLog()

#define LOGTIMER_START    DWORD dwLogTimer = ::GetTickCount();
#define LOGTIMER_LOG(x)   Logger::LogFmt(lsTimer, TEXT("%s: %lu"), TEXT(x), ::GetTickCount() - dwLogTimer);
#define LOGTIMER_UPDATE   dwLogTimer = ::GetTickCount();

#else

#define BEGINLOG(x, s)
#define ENDLOG()

#define LOGTIMER_START
#define LOGTIMER_LOG(x)
#define LOGTIMER_UPDATE

#endif